package com.hbnu.config;

import com.hbnu.service.impl.TouristAuthenticationEntryPointImpl;
import com.hbnu.service.impl.TouristAuthenticationProvider;
import com.hbnu.service.impl.TouristDetailServiceImpl;
import com.hbnu.util.JwtTouristFilter;
import com.ruoyi.framework.config.properties.PermitAllUrlProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Order(2)
public class TouristSecurityConfig {
    @Autowired
    private TouristDetailServiceImpl touristDetailServiceImpl;
    /**
     * 允许匿名访问的地址
     */
    @Autowired
    private PermitAllUrlProperties permitAllUrl;

    //自定义失败类
    @Autowired
    private TouristAuthenticationEntryPointImpl unauthorizedHandler;

//    @Autowired
//    @Qualifier("touristAuthenticationManager")
//    private AuthenticationManager touristAuthenticationManager;

    @Autowired
    private JwtTouristFilter jwtTouristFilter;
    @Bean
    public PasswordEncoder  passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    //有问题AuthenticationManager
    @Bean(name = "touristAuthenticationManager")
    public AuthenticationManager touristAuthenticationManager(HttpSecurity http) throws Exception {
        // 使用 HttpSecurity 的共享对象构建 AuthenticationManager
        AuthenticationManagerBuilder authManagerBuilder =
                http.getSharedObject(AuthenticationManagerBuilder.class);

        // 配置认证提供者
        TouristAuthenticationProvider touristAuthenticationProvider =
                new TouristAuthenticationProvider(touristDetailServiceImpl, passwordEncoder());

        authManagerBuilder.authenticationProvider(touristAuthenticationProvider);

        return authManagerBuilder.build();
    }
    @Order(2)
    @Bean
    protected SecurityFilterChain touristFilterChain(HttpSecurity httpSecurity) throws Exception
    {
        return httpSecurity
//                .securityMatcher("/tourists/**")
                .requestMatchers().antMatchers("/tourists/**")
                .and()
                // 禁用HTTP响应标头
                .headers((headersCustomizer) -> {
                    headersCustomizer.cacheControl(cache -> cache.disable()).frameOptions(options -> options.sameOrigin());
                })
//                .authenticationManager(touristAuthenticationManager)
                .csrf().disable()
                .exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                // 注解标记允许匿名访问的url
                .authorizeHttpRequests((requests) -> {
                    permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
                    // 对于登录login 注册register 验证码captchaImage 允许匿名访问
                    requests.antMatchers("/tourists/login", "/tourists/register", "/tourists/captchaImage", "/tourists/updatePassword","/tourists/getCode","/tourists/findPassword").permitAll()
                            // 静态资源，可匿名访问
                            .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                            .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
                            // 除上面外的所有请求全部需要鉴权认证
                            .antMatchers("/tourists/**").authenticated();
                })
                .addFilterBefore(jwtTouristFilter,  UsernamePasswordAuthenticationFilter.class)
                .build();
    }
}
